package com.blackcat.demo.filter;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import java.io.IOException;

import static org.springframework.util.ObjectUtils.isEmpty;

/**
 * <p> 描述 ：过滤器
 * @author : blackcat
 * @date : 2020/5/20 14:04
 *
 * Filter 对 用户请求 进行 预处理，接着将请求交给 Servlet 进行 处理 并 生成响应，
 *  最后 Filter 再对 服务器响应 进行 后处理。
 * Filter 是可以复用的代码片段，常用来转换 HTTP 请求、响应 和 头信息。
 * Filter 不像 Servlet，它不能产生 响应，而是只 修改 对某一资源的 请求 或者 响应。
 *
 * 过滤器就是筛选出你要的东西，比如requeset中你要的那部分
 * 一个 Servlet 请求可以经由多个 Filter 进行过滤，最终由 Servlet 处理并响应客户端。
 */
@Slf4j
@WebFilter(filterName = "firstIndexFilter",// filter名称
    displayName = "firstIndexFilter",
    urlPatterns = {"/index/*"},// 路径匹配
    initParams = @WebInitParam(
        name = "firstIndexFilterInitParam",
        value = "io.ostenant.springboot.sample.filter.FirstIndexFilter")
)
public class FirstIndexFilter implements Filter {

    /**
     * <p> 描述 : 初始化时，会执行 init() 方法
     * @author : blackcat
     * @date  : 2020/5/20 14:16
    */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("注册过滤器 {}", filterConfig.getFilterName());
    }

    /**
     * <p> 描述 : 过滤请求
     * @author : blackcat
     * @date  : 2020/5/20 14:24
     * @param request 未到达 Servlet 的 HTTP 请求；
     * @param response 由 Servlet 处理并生成的 HTTP 响应；
     * @param chain 过滤器链 对象，可以按顺序注册多个 过滤器。
     * @return void
     * 每次请求路径匹配 urlPatterns 配置的路径时，就会进入 doFilter() 方法进行具体的 请求 和 响应过滤。
     * 一个 过滤器链 对象可以按顺序注册多个 过滤器。符合当前过滤器过滤条件，即请求 过滤成功 直接放行，则交由下一个 过滤器 进行处理。
     * 所有请求过滤完成以后，由 IndexHttpServlet 处理并生成 响应，然后在 过滤器链 以相反的方向对 响应 进行后置过滤处理。
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        log.info("FirstIndexFilter预过滤请求");
        // 当 HTTP 请求携带 filter1 参数时，请求会被放行；否则，直接 过滤中断，结束请求处理。
        String filter = request.getParameter("filter1");
        if (isEmpty(filter)) {// 如果filter1参数为空
            response.getWriter().println("FirstIndexFilter doFilter() \"filter1\"");
            log.info("请设置请求参数 filter1"+filter);
            return;
        }
        chain.doFilter(request, response);
        log.info("FirstIndexFilter对响应进行后筛选");
    }

    @Override
    public void destroy() {
        log.info("注销过滤器 {}", getClass().getName());
    }
}
